/*
 * Copyright (C) 2019 @MTI Ltd.
 *
 */
package com.mti.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mti.component.snowflake.KeyWorker;
import com.mti.constant.ArmingTaskEnum;
import com.mti.dao.model.*;
import com.mti.exception.BusinessException;
import com.mti.jwt.AccountBo;
import com.mti.jwt.RequestUtils;
import com.mti.mapper.ArmingTaskRelationMapper;
import com.mti.mapper.LfZdryBaseMapper;
import com.mti.mapper.LfZdryMapper;
import com.mti.mapper.SpecialPersonArmingTaskMapper;
import com.mti.service.IArmingTaskRelationLogService;
import com.mti.service.ISpecialPersonArmingTaskService;
import com.mti.service.ISysDictService;
import com.mti.vo.ArmingTaskDetailVO;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @company 上海道枢信息科技-->
 * @anthor created by zhangmingxin
 * @date 2019/8/21
 * @change
 * @describe describe
 **/
@Service
@AllArgsConstructor
public class SpecialPersonArmingTaskServiceImpl extends ServiceImpl<SpecialPersonArmingTaskMapper,LfZdryArmingTaskEntity> implements ISpecialPersonArmingTaskService {
    private final ArmingTaskRelationMapper relationMapper;
    private final LfZdryBaseMapper specialMapper;
    private final SpecialPersonArmingTaskMapper armingTaskMapper;
    private final IArmingTaskRelationLogService logService;
    private final RequestUtils requestUtils;
    private final ISysDictService sysDictService;
    @Override
    @Transactional
    public void addSpecialPersonToArmingTask(String taskId,String reportOrg, String specialPersonId,String isSpyAdd, ServerWebExchange exchange) {
        if(StringUtils.isEmpty(specialPersonId)||StringUtils.isEmpty(reportOrg)||StringUtils.isEmpty(taskId))
            throw new BusinessException(500,"相关参数缺失");
        Optional<LfZdryBaseEntity> optional = Optional.ofNullable(specialMapper.selectById(specialPersonId));
        optional.orElseThrow(()->new BusinessException(500,"重点人员不存在"));
        String pk = String.valueOf(KeyWorker.nextId());
        ArmingTaskRelationEntity relationEntity = relationMapper.selectOne(new LambdaQueryWrapper<ArmingTaskRelationEntity>().eq(ArmingTaskRelationEntity::getSpId,specialPersonId).eq(ArmingTaskRelationEntity::getAtId,taskId));
        if(relationEntity==null){//未添加过重点人员才进行添加
            String operation = "";
            if(isSpyAdd!=null && isSpyAdd.equalsIgnoreCase("1")){
                operation = "情报中心添加重点人员";
                optional.ifPresent(item->relationMapper.addSpySpecialPersonToArmingTask(pk,taskId, specialPersonId,reportOrg,item.getZrbm()));
            }else{
                operation = "添加重点人员到布防任务";
                optional.ifPresent(item->relationMapper.addSpecialPersonToArmingTask(pk,taskId, specialPersonId,reportOrg,item.getZrbm()));
            }
            //保存log
            LfZdryArmingTaskOperateLog log = new LfZdryArmingTaskOperateLog();
            log.setId(String.valueOf(KeyWorker.nextId()));
            log.setDescription(operation);
            log.setOperateDateTime(LocalDateTime.now());
            log.setTaskId(taskId);
            log.setRid(pk);
            AccountBo account = requestUtils.getCurrentUser(exchange);
            if(account!=null){
                log.setOperatorDept(account.getOrganizationBo().getName());
                log.setOperator(account.getPersonBo().getName());
            }
            log.setSpId(specialPersonId);
            log.setOperation(operation);
            logService.saveOrUpdate(log);
        }
    }

    @Override
    @Transactional
    public void addSpecialPersonListToArmingTask(String taskId,String reportOrg, String specialPersonIds,String isSpyAdd, ServerWebExchange exchange) {
        if(StringUtils.isEmpty(specialPersonIds)||StringUtils.isEmpty(reportOrg)||StringUtils.isEmpty(taskId))
            throw new BusinessException(500,"相关参数缺失");
        if (!StringUtils.isEmpty(specialPersonIds)) {
            String[] specialPersonIdList = specialPersonIds.split(",");
            if (specialPersonIdList.length > 0){
                for (String s : specialPersonIdList) {
                    this.addSpecialPersonToArmingTask(taskId,reportOrg,s,isSpyAdd,exchange);
                }
            }
        }
    }

    @Override
    @Transactional
    public void delSpecialPersonFromArmingTask(String taskId, String specialPersonId,String reportOrg, ServerWebExchange exchange) {
        Optional<LfZdryBaseEntity> optional = Optional.ofNullable(specialMapper.selectById(specialPersonId));
        optional.orElseThrow(()->new BusinessException(500,"重点人员不存在"));
        ArmingTaskRelationEntity relationEntity = relationMapper.selectOne(
                new LambdaQueryWrapper<ArmingTaskRelationEntity>()
                        .eq(ArmingTaskRelationEntity::getSpId,specialPersonId)
                        .eq(ArmingTaskRelationEntity::getAtId,taskId)
        );
        if(Integer.valueOf(ArmingTaskEnum.FINISH_TYPE.ordinal()).equals(relationEntity.getApproveStatus()))
            throw new BusinessException(500,"人员已经审核完毕不可再删除");
        optional.ifPresent(item->relationMapper.delSpecialPersonFromArmingTask(taskId, specialPersonId,reportOrg,item.getZrbm()));
        //保存log
        LfZdryArmingTaskOperateLog log = new LfZdryArmingTaskOperateLog();
        log.setId(String.valueOf(KeyWorker.nextId()));
        log.setDescription("从布防任务中删除重点人员");
        log.setOperateDateTime(LocalDateTime.now());
        log.setTaskId(taskId);
        log.setRid(relationEntity.getId());
        log.setSpId(specialPersonId);
        AccountBo account = requestUtils.getCurrentUser(exchange);
        if(account!=null){
            log.setOperatorDept(account.getOrganizationBo().getName());
            log.setOperator(account.getPersonBo().getName());
        }
        log.setOperation("从布防任务中删除重点人员");
        logService.saveOrUpdate(log);
    }


    public IPage<LfZdryBaseEntity> getTaskSpecialPersons(ArmingTaskDetailVO vo){
        List<ArmingTaskRelationEntity> personIds = relationMapper.getAllSpecialPersonIdsByTaskId(vo.getTaskId(),vo.getReportOrg(),vo.getZrbm(),StringUtils.isEmpty(vo.getApproveStatus())?null:Arrays.asList(vo.getApproveStatus().split(",")));
        IPage<LfZdryBaseEntity> iPage = new Page<>();
        if (personIds != null && !personIds.isEmpty()){
            Map<String,List<ArmingTaskRelationEntity>> groupPerson = personIds.stream().collect(Collectors.groupingBy(ArmingTaskRelationEntity::getSpId));
            QueryWrapper<LfZdryBaseEntity> queryWrapper = new QueryWrapper<>();
            if (!StringUtils.isEmpty(vo.getName())) {
                queryWrapper.lambda().and(
                        wrapper -> wrapper.like(LfZdryBaseEntity::getSfzh, vo.getName())
                                .or().like(LfZdryBaseEntity::getSjh, vo.getName())
                                .or().like(LfZdryBaseEntity::getXm, vo.getName()));
            }
            if (!StringUtils.isEmpty(vo.getOid()))
                queryWrapper.lambda().in(LfZdryBaseEntity::getSspcsId,Arrays.asList(vo.getOid().split(",")));
            if (!StringUtils.isEmpty(vo.getIdentityId()))
                queryWrapper.lambda().like(LfZdryBaseEntity::getSfzh,vo.getIdentityId());
            if (!StringUtils.isEmpty(vo.getSsxq()))
                queryWrapper.lambda().in(LfZdryBaseEntity::getSsxq,Arrays.asList(vo.getSsxq().split(",")));
            if (!StringUtils.isEmpty(vo.getPhoneNumber()))
                queryWrapper.lambda().like(LfZdryBaseEntity::getSjh,vo.getPhoneNumber());
            if (!StringUtils.isEmpty(vo.getPersonName()))
                queryWrapper.lambda().like(LfZdryBaseEntity::getXm,vo.getPersonName());
            if (!StringUtils.isEmpty(vo.getIsControl()))
                queryWrapper.lambda().eq(LfZdryBaseEntity::getSfzk,vo.getIsControl());
//            if(!StringUtils.isEmpty(vo.getRylx()))
//                queryWrapper.lambda().eq(LfZdryBaseEntity::getr,vo.getRylx());
            queryWrapper.lambda().in(LfZdryBaseEntity::getId,personIds.stream().map(ArmingTaskRelationEntity::getSpId).collect(Collectors.toList()));
            iPage = specialMapper.selectPage(new Page<>(vo.getPage(),vo.getSize()),queryWrapper);
            //设置状态
            iPage.getRecords().forEach(r->{
                List<ArmingTaskRelationEntity> inList = groupPerson.get(r.getId());
                if(inList!=null && !inList.isEmpty()){
                    r.setApproveStatus(String.valueOf(inList.get(0).getApproveStatus()));
                    r.setRid(inList.get(0).getId());
                }
            });
        }
        return iPage;
    }

    @Override
    public Page<LfZdryArmingTaskEntity> getTaskList(
            Integer page,
            Integer size,
            String taskName,
            Integer specialLevel,
            Integer status,
            String armingRange,
            String armingRangeId,
            String orgId,
            String oid,
            String zrbm,
            String approveStatus
    ) {
        Page<LfZdryArmingTaskEntity> listPage = new Page<>();
        /**
         * 131002000000
         */
        if(!StringUtils.isEmpty(armingRangeId))
            armingRangeId = armingRangeId.substring(0,6);
//        if(!StringUtils.isEmpty(armingRange))
//            armingRange = armingRange.replace("区","");
        listPage.setRecords(relationMapper.listTask(page <= 1 ? 0 : page - 1, size, taskName, specialLevel,status, armingRange,armingRangeId,orgId,oid,zrbm,StringUtils.isEmpty(approveStatus)?null:Arrays.asList(approveStatus.split(","))));
        listPage.setTotal(relationMapper.listTaskCountRows(taskName, specialLevel,status, armingRange,armingRangeId,orgId,oid,zrbm));
        return listPage;
    }

    @Override
    @Transactional
    public void armingTaskOperation(String operate, String taskId) {
        if (StringUtils.isEmpty(taskId))
            throw new BusinessException(500,"taskId不能为空!!!");
        if (StringUtils.isEmpty(operate))
            throw new BusinessException(500,"操作类型不能为空!!!");
        if (!"1".equalsIgnoreCase(operate) && !"0".equalsIgnoreCase(operate))
            throw new BusinessException(500,"不合法的操作类型!!!");
        UpdateWrapper<LfZdryArmingTaskEntity> queryWrapper = new UpdateWrapper<>();
        queryWrapper.eq("id",taskId);
        if ("1".equalsIgnoreCase(operate)){//启动
            queryWrapper.set("status",1);
        }
        if ("0".equalsIgnoreCase(operate)){//停止
            queryWrapper.set("status",2);
        }
        this.update(queryWrapper);
        //更新所有的关联重点人员为已结束状态
    }

    @Override
    @Transactional
    public void armingTaskReport(String taskId,String reportOrgId,String reportUserId,String reportUserName,String rid,String type,String isSpyAdd, ServerWebExchange exchange) {
        if(StringUtils.isEmpty(taskId))
            throw new BusinessException(500,"布防任务ID不能为空");
        String[] rids = rid.split(",");
        List<String> ridList = Arrays.asList(rids);
        if(rids.length<=0)
            throw new BusinessException(500,"人员关联ID不能为空");
        Optional<LfZdryArmingTaskEntity> taskEntity = Optional.of(armingTaskMapper.selectById(taskId));
        taskEntity.orElseThrow(()->new BusinessException(500,"未查找到对应的布防任务"));
        List<ArmingTaskRelationEntity> relationEntityList = relationMapper.selectList(new LambdaQueryWrapper<ArmingTaskRelationEntity>().in(ArmingTaskRelationEntity::getId,ridList));
        AccountBo account = requestUtils.getCurrentUser(exchange);
        List<LfZdryArmingTaskOperateLog> logs = new ArrayList<>();
        if("1".equalsIgnoreCase(type)){
            if(relationEntityList!=null && !relationEntityList.isEmpty()){
                long result = relationEntityList.stream().filter(item->ArmingTaskEnum.RECALL_TYPE.ordinal()!=item.getApproveStatus() && ArmingTaskEnum.REPORTING_TYPE.ordinal()< item.getApproveStatus() && item.getApproveStatus() <ArmingTaskEnum.REBACK_FINISH_TYPE.ordinal()).count();
                if(result>0)
                    throw new BusinessException(500,"本次上报人员中存在已上报完成人员!");
            }
            taskEntity.ifPresent(item->{
                //更新所有关联的重点人员状态为等待警种审核
                relationMapper.updateSpecialPersonToTargetStatus(taskId,reportOrgId,ArmingTaskEnum.WAIT_SSXQ_POLICE_TYPE_TYPE.ordinal(),ridList);
//                List<ArmingTaskRelationEntity> relationEntities = relationMapper.selectBatchIds(ridList);
                Optional.ofNullable(relationEntityList).ifPresent(l->l.stream().forEach(r->{
                    //保存log
                    LfZdryArmingTaskOperateLog log = new LfZdryArmingTaskOperateLog();
                    log.setId(String.valueOf(KeyWorker.nextId()));
                    log.setDescription("上报重点人员");
                    log.setOperateDateTime(LocalDateTime.now());
                    log.setTaskId(taskId);
                    log.setRid(r.getId());
                    log.setSpId(r.getSpId());
                    if(account!=null){
                        log.setOperatorDept(account.getOrganizationBo().getName());
                        log.setOperator(account.getPersonBo().getName());
                    }
                    log.setOperation("上报重点人员");
                    logs.add(log);
                }));
            });
        }else{
            if(relationEntityList!=null && !relationEntityList.isEmpty()){
                long result = relationEntityList.stream().filter(item->item.getApproveStatus()>ArmingTaskEnum.FINISH_TYPE.ordinal() && !Integer.valueOf(ArmingTaskEnum.REBACK_RECALL_TYPE.ordinal()).equals(item.getApproveStatus())).count();
                if(result>0)
                    throw new BusinessException(500,"本次撤销人员中存在不合法状态人员!");
                if(StringUtils.isEmpty(isSpyAdd) || !isSpyAdd.equalsIgnoreCase("1")){
                    List<String> cancelList = relationEntityList
                            .stream()
                            .filter(item->item.getApproveStatus()<ArmingTaskEnum.FINISH_TYPE.ordinal())
                            .map(r->{
                                //保存log
                                LfZdryArmingTaskOperateLog log = new LfZdryArmingTaskOperateLog();
                                log.setId(String.valueOf(KeyWorker.nextId()));
                                log.setDescription("撤销布控人员");
                                log.setOperateDateTime(LocalDateTime.now());
                                log.setTaskId(taskId);
                                log.setRid(r.getId());
                                log.setSpId(r.getSpId());
                                if(account!=null){
                                    log.setOperatorDept(account.getOrganizationBo().getName());
                                    log.setOperator(account.getPersonBo().getName());
                                }
                                log.setOperation("撤销布控人员");
                                logs.add(log);
                                return r.getId();
                            }).collect(Collectors.toList());
                    if(!cancelList.isEmpty())
                        relationMapper.updateSpecialPersonToTargetStatus(taskId,reportOrgId,ArmingTaskEnum.REPORTING_TYPE.ordinal(),cancelList);
                }
                List<String> updateList = relationEntityList
                        .stream()
                        .filter(item->item.getApproveStatus()==ArmingTaskEnum.FINISH_TYPE.ordinal())
                        .map(r->{
                            //保存log
                            LfZdryArmingTaskOperateLog log = new LfZdryArmingTaskOperateLog();
                            log.setId(String.valueOf(KeyWorker.nextId()));
                            log.setDescription("申请撤销布控人员");
                            log.setOperateDateTime(LocalDateTime.now());
                            log.setTaskId(taskId);
                            log.setRid(r.getId());
                            log.setSpId(r.getSpId());
                            if(account!=null){
                                log.setOperatorDept(account.getOrganizationBo().getName());
                                log.setOperator(account.getPersonBo().getName());
                            }
                            log.setOperation("申请撤销布控人员");
                            logs.add(log);
                            return r.getId();
                        }).collect(Collectors.toList());
                if(!updateList.isEmpty())
                    relationMapper.updateSpecialPersonToTargetStatus(taskId,reportOrgId,!StringUtils.isEmpty(isSpyAdd) && isSpyAdd.equalsIgnoreCase("1")?ArmingTaskEnum.REBACK_FINISH_TYPE.ordinal():ArmingTaskEnum.WAIT_SSXQ_POLICE_TYPE_REBACK.ordinal(),updateList);
            }
        }
        if(!logs.isEmpty())
            logService.saveBatch(logs);
    }
}
